import axios, { AxiosError } from "axios";
import type { AxiosResponse } from "axios";
import type { InternalAxiosRequestConfig } from "axios";
import type { AxiosRequestConfig } from "axios";
import { getMessageInfo } from "./status";
import { ElMessage } from "element-plus";

interface BaseResponse<T = any> {
  code: number;
  message: string;
  data: T;
}

const service = axios.create({
  baseURL: "/",
  timeout: 10000,
});

// 请求拦截器
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    return config;
  },
  (error: AxiosError) => {
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse) => {
    const { code } = response.data;
    if (code !== 200) {
      ElMessage({ message: getMessageInfo(code), type: "error" });
      return response;
    }
    return response;
  },
  (error) => {
    const { response } = error;
    if (response) {
      const { status } = response;
      ElMessage({ message: getMessageInfo(status), type: "error" });
      return Promise.reject(error);
    }
    ElMessage({ message: "网络连接异常,请稍后再试!", type: "error" });
  }
);

// 请求的第二次拦截器
const requestInstance = <T = any>(config: AxiosRequestConfig): Promise<T> => {
  const conf = config;
  return new Promise((resolve, reject) => {
    service
      .request<any, AxiosResponse<BaseResponse>>(conf)
      .then((res: AxiosResponse<BaseResponse>) => {
        const data = res.data;
        if (data.code != 200) {
          reject(data.message);
        } else {
          resolve(data.data as T);
        }
      });
  });
};
export function get<T = any, U = any>(
  config: AxiosRequestConfig,
  url: string,
  params?: U
): Promise<T> {
  return new Promise((resolve, reject) => {
    requestInstance<T>({ ...config, url, method: "GET", params })
      .then((res: string | T) => resolve(res as T))
      .catch((error) => reject(error));
  });
}
export function post<T = any, U = any>(
  config: AxiosRequestConfig,
  url: string,
  data?: U
): Promise<T> {
  return new Promise((resolve, reject) => {
    requestInstance<T>({ ...config, url, method: "POST", data })
      .then((res: string | T) => resolve(res as T))
      .catch((error) => reject(error));
  });
}

export default service;
